#ifndef __GSM__WATCHER_H__
#define __GSM__WATCHER_H__

#include <glib-object.h>
#include <gio/gio.h>

G_BEGIN_DECLS

#define GSM_TYPE_WATCHER			(gsm_watcher_get_type ())
#define GSM_WATCHER(obj)			(G_TYPE_CHECK_INSTANCE_CAST ((obj), GSM_TYPE_WATCHER, GsmWatcher))
#define GSM_WATCHER_CLASS(klass)	(G_TYPE_CHECK_CLASS_CAST ((klass), GSM_TYPE_WATCHER, GsmWatcherClass))
#define GSM_IS_WATCHER(obj)			(G_TYPE_CHECK_INSTANCE_TYPE ((obj), GSM_TYPE_WATCHER))
#define GSM_IS_WATCHER_CLASS(klass)	(G_TYPE_CHECK_CLASS_TYPE ((klass), GSM_TYPE_WATCHER))
#define GSM_WATCHER_GET_CLASS(obj)	(G_TYPE_INSTANCE_GET_CLASS ((obj), GSM_TYPE_WATCHER, GsmWatcherClass))

enum {
	GSM_WATCHER_ERROR_NONE,
	GSM_WATCHER_ERROR_TIMEOUT
};

typedef struct {
	gchar *name;
	GType type;
} GsmPlayerParameter;

typedef struct _GsmWatcher GsmWatcher;
typedef struct _GsmWatcherClass GsmWatcherClass;
typedef struct _GsmPlayer GsmPlayer;

struct _GsmWatcher {
	GObject parent_object;
	
	gchar *address;
	GSocketAddress *sockaddr;
	GTimer *timer;
	gboolean has_sent;
	
	GsmPlayerParameter *params;
	gchar name[128];
	gchar map[64];
	gint8 num_players;
	gint8 max_players;
	gchar version[64];
	gchar game[64];
	gchar *icon;
	GSList *players;
	glong ping;
};

struct _GsmWatcherClass {
	GObjectClass parent_class;
	
	guint16 default_port;
	
	// signals
	void (*updated) (GsmWatcher *watcher, gpointer user_data);
	void (*error) (GsmWatcher *watcher, GError *error, gpointer user_data);
	void (*player_online) (GsmWatcher *watcher, GsmPlayer *player, gpointer user_data);
	void (*player_offline) (GsmWatcher *watcher, GsmPlayer *player, gpointer user_data);
	
	void (*resolved) (GsmWatcher *watcher, guint16 *port);
	void (*update) (GsmWatcher *watcher);
	gboolean (*process_respond) (GsmWatcher *watcher, const gchar *buffer,
			gsize size);
};

struct _GsmPlayer {
	gchar name[128];
	GValue *values;
	GsmWatcher *watcher;
};

GType gsm_watcher_get_type (void) G_GNUC_CONST;
guint16 gsm_watcher_get_default_port (GsmWatcher *watcher);

void gsm_watcher_update (GsmWatcher *watcher);
void gsm_watcher_send (GsmWatcher *watcher, const gchar *buffer, gsize size);
void gsm_watcher_update_players_list (GsmWatcher *watcher, GSList *new_list);

void gsm_watcher_set_address (GsmWatcher *watcher, const gchar *address);
const gchar *gsm_watcher_get_address (GsmWatcher *watcher);

G_END_DECLS

#endif